import tkinter as tk
import threading
import time
import queue
import tkinter as tk
from tkinter import ttk, messagebox
import tushare as ts
import logging

# 导入组件和工具类
from trading.core.config import Config
from trading.core.data_model import MarketData
from trading.ui.stock_info_panel import StockInfoPanel
from trading.ui.combined_chart import CombinedChart
from trading.ui.control_panel import ControlPanel
from trading.ui.deal_details import DealDetails
from trading.ui.backtest_panel import BacktestPanel

from trading.core.data_fetcher import DataFetcher

logger = logging.getLogger(__name__)


class AShareRealTimeMonitor:
    """A股实时行情监控主控制器"""

    def __init__(self, root: tk.Tk):
        self.root = root
        self._setup_window()

        # 状态变量
        self.running = False
        self.ts_api = None  # Tushare API实例
        self.current_code = None  # 当前监控的股票代码
        self.market_data = MarketData()  # 市场数据缓存

        # 线程通信队列
        self.data_queue = queue.Queue()

        # 初始化UI和数据处理线程
        self._setup_ui()
        self._start_data_processing_thread()

    def _setup_window(self):
        """配置主窗口属性"""
        self.root.title(Config.WINDOW_TITLE)
        self.root.geometry(Config.WINDOW_SIZE)
        self.root.minsize(*Config.WINDOW_MIN_SIZE)
        self.root.protocol("WM_DELETE_WINDOW", self.on_close)

    def _setup_ui(self):
        """初始化UI组件"""
        # 顶部控制面板
        self.control_panel = ControlPanel(
            self.root,
            on_connect=self._connect_api,
            on_add_monitor=self._add_monitor
        )

        # 创建标签页控件
        self.tab_control = ttk.Notebook(self.root)
        self.tab_control.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

        # 实时监控标签页
        monitor_tab = ttk.Frame(self.tab_control)
        self.tab_control.add(monitor_tab, text="实时监控")

        # 主内容区（左右分栏）
        main_frame = ttk.PanedWindow(monitor_tab, orient=tk.HORIZONTAL)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

        # 左侧：股票信息面板
        self.stock_info = StockInfoPanel(main_frame)
        main_frame.add(self.stock_info.frame, weight=1)

        # 右侧：图表和成交明细（上下分栏）
        right_panel = ttk.PanedWindow(main_frame, orient=tk.VERTICAL)
        main_frame.add(right_panel, weight=3)

        # 图表区域
        self.combined_chart = CombinedChart(right_panel)
        right_panel.add(self.combined_chart.frame, weight=3)

        # 成交明细区域
        self.deal_details = DealDetails(right_panel)
        right_panel.add(self.deal_details.frame, weight=1)

        # 历史回测标签页
        backtest_tab = ttk.Frame(self.tab_control)
        self.tab_control.add(backtest_tab, text="历史回测")

        # 初始化回测面板
        self.backtest_panel = BacktestPanel(backtest_tab, None)
        self.backtest_panel.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

    def _start_data_processing_thread(self):
        """启动数据处理线程（负责更新UI）"""
        self.process_thread = threading.Thread(
            target=self._process_data,
            daemon=True
        )
        self.process_thread.start()

    def _connect_api(self):
        """连接Tushare API"""
        token = self.control_panel.get_token()
        if not token:
            messagebox.showerror("错误", "请输入Tushare Token")
            return

        try:
            ts.set_token(token)
            self.ts_api = ts.pro_api()
            # 更新回测面板的数据获取器
            if hasattr(self, 'backtest_panel'):
                self.backtest_panel.data_fetcher = DataFetcher(self.ts_api)
            messagebox.showinfo("成功", "行情接口连接成功")
        except Exception as e:
            messagebox.showerror("连接失败", f"API初始化错误: {str(e)}")

    def _add_monitor(self):
        """添加股票监控"""
        if not self.ts_api:
            messagebox.showerror("错误", "请先连接行情接口")
            return

        code = self.control_panel.get_stock_code()
        if not code:
            messagebox.showerror("错误", "请输入股票代码")
            return

        self.current_code = code
        self.root.title(f"{Config.WINDOW_TITLE} - {code}")

        # 启动数据获取线程
        if not self.running:
            self.running = True
            self.data_thread = threading.Thread(
                target=self._fetch_data_loop,
                daemon=True
            )
            self.data_thread.start()

        # 立即获取一次数据
        self._fetch_data()

    def _fetch_data_loop(self):
        """循环获取数据（定时任务）"""
        while self.running and self.current_code:
            start_time = time.time()
            self._fetch_data()  # 获取数据

            # 计算实际等待时间（扣除数据获取耗时）
            elapsed = time.time() - start_time
            sleep_time = max(0, self.control_panel.get_refresh_interval() - elapsed)
            time.sleep(sleep_time)

    def _fetch_data(self):
        """单次数据获取"""
        if not self.ts_api or not self.current_code:
            return

        # 实例化数据获取器并获取数据
        data_fetcher = DataFetcher(self.ts_api, self.data_queue)
        data = data_fetcher.fetch_data(self.current_code)

        if data:
            self.data_queue.put(data)  # 发送到队列

    def _process_data(self):
        """处理队列中的数据并更新UI"""
        while True:
            try:
                # 从队列获取数据（超时1秒）
                data = self.data_queue.get(timeout=1)
                self.market_data = data

                # 用root.after确保UI更新在主线程执行
                self.root.after(0, self._update_ui, data)

            except queue.Empty:
                continue  # 队列为空时继续等待
            except Exception as e:
                logger.error(f"数据处理失败: {str(e)}")

    def _update_ui(self, data: MarketData):
        """更新所有UI组件"""
        try:
            self.stock_info.update_data(data)
            self.deal_details.update_deals(data.deals, data.close)
            self.combined_chart.update_data(data, self.current_code)
        except Exception as e:
            logger.error(f"UI更新失败: {str(e)}")

    def on_close(self):
        """窗口关闭时的资源清理"""
        self.running = False  # 停止数据获取线程

        # 等待线程结束（最多等待2秒）
        if hasattr(self, 'data_thread') and self.data_thread.is_alive():
            self.data_thread.join(timeout=2)

        self.root.destroy()  # 销毁窗口